package com.ming.core.builder;

import cn.hutool.json.JSONUtil;

import java.util.*;

public class VueFlowBuilder implements FlowBuilder {

    private FlowBuilderContext context;

    private boolean format = true;

    private Map<String,Object> flowMap = new LinkedHashMap<>();
    private List<Map<String,Object>> nodes = new ArrayList<>();
    private List<Map<String,Object>> edges = new ArrayList<>();

    @Override
    public FlowBuilder context(FlowBuilderContext context) {
        this.context = context;
        return this;
    }

    @Override
    public FlowBuilder addNode(Map<String,Object> nodeMap) {
        return this;
    }

    @Override
    public FlowBuilder addEdge(Map<String,Object> nodeMap) {
        return this;
    }

    @Override
    public FlowBuilder format(boolean format) {
        this.format = format;
        return this;
    }

    @Override
    public FlowBuilder flowJson(String flowJson) {
        Map map = JSONUtil.parseObj(flowJson).toBean(Map.class);
        if (map.containsKey(context.getMappingNodes())) {
            List<Map<String,Object>> nodes = (List<Map<String, Object>>) map.get(context.getMappingNodes());
            for (Map<String,Object> nodeMap : nodes){
                Map<String,Object> node = new LinkedHashMap<>();
                node.put(FlowBuilderContext.NODE_ID, nodeMap.get(context.getMappingNodeId()));
                node.put(FlowBuilderContext.NODE_TYPE, nodeMap.get(context.getMappingNodeType()));
                node.put(FlowBuilderContext.NODE_LABEL, nodeMap.get(context.getMappingNodeLabel()));
                node.put(FlowBuilderContext.NODE_DATA, nodeMap.get(context.getMappingNodeData()));
                this.nodes.add(node);
            }
        }
        if (map.containsKey(context.getMappingEdges())) {
            List<Map<String,Object>> edges = (List<Map<String, Object>>) map.get(context.getMappingEdges());
            for (Map<String,Object> edgeMap : edges){
                Map<String,Object> edge = new LinkedHashMap<>();
                edge.put(FlowBuilderContext.EDGE_ID, edgeMap.get(context.getMappingEdgeId()));
                edge.put(FlowBuilderContext.EDGE_TYPE, edgeMap.get(context.getMappingEdgeType()));
                edge.put(FlowBuilderContext.EDGE_SOURCE, edgeMap.get(context.getMappingEdgeSource()));
                edge.put(FlowBuilderContext.EDGE_TARGET, edgeMap.get(context.getMappingEdgeTarget()));
                edge.put(FlowBuilderContext.EDGE_DATA, edgeMap.get(context.getMappingEdgeData()));
                this.edges.add(edge);
            }
        }
        return this;
    }

    @Override
    public String build() {
        flowMap.put(FlowBuilderContext.NODES, nodes);
        flowMap.put(FlowBuilderContext.EDGES, edges);
        if(format){
            return JSONUtil.toJsonPrettyStr(flowMap);
        }
        return JSONUtil.toJsonStr(flowMap);
    }

}
